<?php
require './function.php';
/**
 * @Author: Wherein
 * @Date: 2021-04-16 12:59
 * @Descripttion: 观察者模式
 */

// 抽象观察者接口
Interface Observer{
    public function update();
}

abstract class Subject{
    // 定义一个观察者数组
    private $observers = array();
    // 增加观察者的方法
    public function addObserver(Observer $observer){
        $this->observers[] = $observer;
        dd('添加观察者成功');
    }

    // 删除观察者
    public function delObserver(Observer $observer){
        $key = array_search($observer, $this->observers);
        // 判断是否有观察者存在
        if ($observer===$this->observers[$key]) {
            // 值虽然相同,但有可能不是同一个对象,所以使用全等判断
            unset($this->observers[$key]);
            dd('删除观察者成功');
        } else {
            dd('观察者不存在,无需删除');
        }
    }

    // 通知所有观察者
    public function notifyObservers(){
        foreach ($this->observers as $observer) {
            $observer->update();
        }
    }
}

// 具体被观察者  服务端
class Server extends Subject{
    // 具体被观察者业务, 发布一条信息,并通知所有客户端
    public function publish(){
        dd('项目版本更新: 10.0');
        $this->notifyObservers();
    }
}

// 具体观察者类
// 微信端
class Wechat implements Observer{
    public function update(){
        dd('微信更新中');
    }
}

// web端
class Web implements Observer{
    public function update(){
        dd('web端更新中');
    }
}

// app端
class App implements Observer{
    public function update(){
        dd('app端更新中');
    }
}

// 实例化被观察者
$server = new Server();
// 实例化观察者
$wechat = new Wechat();
$web = new Web();
$app = new App();
// 添加被观察者
$server->addObserver($wechat);
$server->addObserver($web);
$server->addObserver($app);
// 被观察者 发布信息
$server->publish();

// 删除观察者
$server->delObserver($wechat);
// 再次发布信息
$server->publish();

// 尝试删除一个未添加成观察者的对象
$server->delObserver(new Web);
// 再次发布信息
$server->publish();